package com.springboot.rigger.modules.controller;

import com.google.common.base.Joiner;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.springboot.rigger.common.config.FilesUtils;
import com.springboot.rigger.common.config.MD5Utils;
import com.springboot.rigger.dto.CommonResult;
import com.springboot.rigger.enums.BusinessExceptionEnum;
import com.springboot.rigger.exception.GlobalException;
import com.springboot.rigger.modules.entity.Users;
import com.springboot.rigger.modules.service.TestService;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.file.Paths;
import java.util.*;

/**
 * @Description:
 * @title: TestController
 * @Author Star_Chen
 * @Date: 2021/12/23 10:55
 * @Version 1.0
 */
@RestController
@RequestMapping(value = "/api")
public class TestController {

    @Autowired
    private TestService testService;

    /**
     * @Date: 2021/12/24 9:05
     * @Author: Star_Chen
     * @Description: 测试接口demo
     * @Return: {@link null}
     */
    @RequestMapping(value = "/test", method = RequestMethod.GET/*, consumes = "application/json"*/)
    public List<Users> test() {

        List<Users> userList = testService.getUserByOneList();
        return userList;
    }

    /**
     * @Date: 2022/4/8 15:36
     * @Author: Star_Chen
     * @Param: * @param null
     * @Description: 业务异常处理demo
     */
    @RequestMapping(value = "/testException", method = RequestMethod.GET/*, consumes = "application/json"*/)
    public List<Users> testException(String id) {

        if (StringUtils.isEmpty(id)) {
            throw new GlobalException(BusinessExceptionEnum.CONFIG_NOT_EXIST);
        }

        List<Users> userList = testService.getUserByOneList();
        if (userList.size() == 0 || userList == null) {
            throw new GlobalException(BusinessExceptionEnum.DATA_IS_NULL);
        }

        return userList;
    }


    /**
     * @Date: 2022/4/8 15:36
     * @Author: Star_Chen
     * @Param: * @param null
     * @Description: 形参传递校验demo
     * 注意区分@Validated  和 @RequestBody
     */
    @RequestMapping(value = "/testValidated", method = RequestMethod.POST/*, consumes = "application/json"*/)
    public List<Users> testValidated(@Validated @RequestBody Users users) {

        if (StringUtils.isEmpty(users.getName())) {
            throw new GlobalException(BusinessExceptionEnum.PARAM_IS_NULL);
        }

        List<Users> userList = testService.getUserByOneList();
        if (userList.size() == 0 || userList == null) {
            throw new GlobalException(BusinessExceptionEnum.DATA_IS_NULL);
        }

        return userList;
    }


    public static void main(String[] args) {
        FileFilter fileFilter = new FileFilter() {
            @Override
            public boolean accept(File file) {
                return !(".svn".equals(file.getName()) || "target".equals(file.getName()) || "bin".equals(file.getName()) || ".project".equals(file.getName()) || ".settings".equals(file.getName()) || "classes".equals(file.getName()) || file.getName().endsWith(".class"));
            }
        };

        String leftPath = "C:\\Users\\Administrator\\Desktop\\lib1.8";
        String rightPath = "C:\\Users\\Administrator\\Desktop\\lib1.7";
        MapDifference<String, String> difference = difference(leftPath, rightPath, fileFilter);
        if (difference.areEqual()) {
            System.out.println("两个路径下文件完全相同!");
        } else {
            System.out.println("两个路径下文件差异：");

            System.out.println("------1.8有而1.7没有的 size: " + difference.entriesOnlyOnLeft().size() + ", " + leftPath + "\n");
            difference.entriesOnlyOnLeft().entrySet().forEach(System.out::println);

            System.out.println("-----1.7有而1.8没有的: " + difference.entriesOnlyOnRight().size() + ", " + rightPath + "\n");
            difference.entriesOnlyOnRight().entrySet().forEach(System.out::println);

            System.out.println("-------Differing size: " + difference.entriesDiffering().size());
            difference.entriesDiffering().entrySet().forEach(System.out::println);
        }
    }

    private static MapDifference<String, String> difference(String leftPath, String rightPath, FileFilter fileFilter) {
        Map<String, String> left = getAllFilesMD5(leftPath, fileFilter);
        Map<String, String> right = getAllFilesMD5(rightPath, fileFilter);
        return Maps.difference(left, right);
    }

    private static Map<String, String> getAllFilesMD5(String dirPth, FileFilter fileFilter) {
        Map<String, String> map = new HashMap<String, String>();
        int index = dirPth.length();
        List<File> allFiles = FilesUtils.getAllFiles(dirPth, fileFilter);
        for (File file : allFiles) {
            if (file.isDirectory()) {
                map.put(file.getPath().substring(index), "isDir");
            } else {
                map.put(file.getPath().substring(index), MD5Utils.md5(file));
            }
        }
        return map;
    }


    @GetMapping("/getHtml")
    public String getHtml() {
        String html = "<html>\n" + "<head>\n" + "    <title>传智播客官网-一样的教育,不一样的品质</title>\n" + "</head>\n" + "<body>\n" + "<div class=\"city\">\n" + "    <h3 id=\"city_bj\">北京中心</h3>\n" + "    <img src=\"/2018czgw/images/slogan.jpg\" class=\"slogan\"/>\n" + "    <div class=\"city_in\">\n" + "        <div class=\"city_con\" style=\"display: none;\">\n" + "            <ul>\n" + "                <li id=\"test\" class=\"class_a class_b\">\n" + "                    <a href=\"http://www.itcast.cn\" target=\"_blank\">\n" + "                        <span class=\"s_name\">北京</span>\n" + "                    </a>\n" + "                </li>\n" + "                <li>\n" + "                    <a href=\"http://sh.itcast.cn\" target=\"_blank\">\n" + "                        <span class=\"s_name\">上海</span>\n" + "                    </a>\n" + "                </li>\n" + "                <li>\n" + "                    <a href=\"http://gz.itcast.cn\" target=\"_blank\">\n" + "                        <span abc=\"123\" class=\"s_name\">广州</span>\n" + "                    </a>\n" + "                </li>\n" + "                <ul>\n" + "                    <li>天津</li>\n" + "                </ul>\n" + "            </ul>\n" + "        </div>\n" + "    </div>\n" + "</div>\n" + "</body>\n" + "</html>\n" + "\n";
        //解析字符串
        Document document = Jsoup.parse(html);
        //获取title的内容
        Elements imgList = document.body().getElementsByTag("img");
        List<String> retList = new ArrayList<>();
        for (Element element : imgList) {
            String src = element.attr("src");//获取src属性值
            // TODO 处理src属性值
            retList.add(src);
        }

        return Joiner.on(",").join(retList);
    }

    @PostMapping("/upload1")
    public String upload1(@RequestParam("file") MultipartFile multipartFile,HttpServletRequest request) throws IOException, FileUploadException {
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "/static/images";
        System.out.println("上传的文件地址是：" + realPath);
        // 服务器中对应的位置
        // 产生唯一的文件名称
        String fileName = String.valueOf(UUID.randomUUID());
        // 获取到文件后缀
        String fileType = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        File src = new File(realPath, fileName + fileType);
        // 将file文件传递到src去
        multipartFile.transferTo(src);
        return "images/" + fileName + fileType;
    }


    @PostMapping("/upload")
    public String upload(HttpServletRequest request) throws IOException, FileUploadException {

        CommonResult commonResult = CommonResult.newInstance();
        request.setCharacterEncoding("utf-8");
        if (ServletFileUpload.isMultipartContent(request)) {
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();// 创建该对象
            ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);// 创建该对象
            FileItemIterator itemIterator = fileUpload.getItemIterator(request);// 解析request 请求,并返回FileItemIterator集合
            StringBuffer fileContent = new StringBuffer();
            while (itemIterator.hasNext()) {
                FileItemStream itemStream = itemIterator.next();//从集合中获得一个文件流
                if (!itemStream.isFormField() && itemStream.getName().length() > 0) {    //过滤掉表单中非文件
                    BufferedInputStream inputStream = new BufferedInputStream(itemStream.openStream());   //获得文件输入流
                    inputStream.mark(itemStream.openStream().available() + 1);
                    //判断上传的文件的编码格式 支持 UTF-8 和 ANSI两种类型
                    String charsetName = getFileCharsetName(inputStream);

                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charsetName));
                    String lineTxt = null;
                    while ((lineTxt = bufferedReader.readLine()) != null) {
                        fileContent.append(lineTxt + "\r");
                    }

                }
            }
            commonResult.setData(fileContent.toString());
            return fileContent.toString();
        }

        return null;

    }


    private static String getFileCharsetName(InputStream inputStream) throws IOException {
        String charsetName = "GBK";
        byte[] typeByte = new byte[3];

        inputStream.read(typeByte);
        if (typeByte[0] == -17 && typeByte[1] == -69 && typeByte[2] == -65) {
            charsetName = "UTF-8";
        } else {
            charsetName = "GBK";
        }
        inputStream.reset();
        return charsetName;
    }



    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void uploadFile(HttpServletRequest request) throws IOException {

        // 强制将HttpServletRequest转为MultipartHttpServletRequest
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        //获取指定MultipartFile文件
        MultipartFile file = multipartRequest.getFile("file");
        //获取文件名称
        String originalFilename = file.getOriginalFilename();
        //保存上传文件到xxx路径
        file.transferTo(Paths.get("C:\\Users\\Administrator\\Desktop\\2323\\1.txt"));

        //不指定上传文件参数,而是获取整个上传文件集合
        MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
        //遍历整个上传文件集合，获取上传文件
        Iterator<String> MultipartFileIterator = multiFileMap.keySet().iterator();
        while (MultipartFileIterator.hasNext()) {
            String key = MultipartFileIterator.next();
            //这里是集合的原因是，可能一个参数上传多个文件。
            List<MultipartFile> multipartFiles = multiFileMap.get(key);
            System.out.println("当前上传文件参数: " + key);
            multipartFiles.forEach(multipartFile -> {
                System.out.println("上传文件名称: " + multipartFile.getOriginalFilename() + ", 上传文件类型:" + multipartFile.getContentType());
            });
            System.out.println("------------分割----------");
        }
    }


}
